package com.hsyt.pms.org.dubbo.impl;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;

//@Component
@Configuration
public class ElasticSearchClientFactoryBean implements FactoryBean<TransportClient>, InitializingBean,
        DisposableBean {

    private TransportClient transportClient;

    private String clusterName = "yt-spring-boot-index";

    private String hostList = "localhost:9300";

    @Value("${elasticsearch.host}")
    private String EsHost;

    @Value("${elasticsearch.port}")
    private int EsPort;

    @Value("${elasticsearch.clustername}")
    private String clusterNameAuto;

    @Override
    public TransportClient getObject() throws Exception {
        if (transportClient == null) {
            throw new IllegalStateException("初始化 ElasticSearch 客户端异常.");
        }
        return transportClient;
    }

    @Override
    public Class<?> getObjectType() {
        return TransportClient.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    @Override
    public void destroy() throws Exception {
        transportClient.close();
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if(!StringUtils.isEmpty(clusterNameAuto)){
            clusterName = clusterNameAuto;
        }
        if(!StringUtils.isEmpty(EsHost)){
            hostList = EsHost + ":" + EsPort;
        }
        if (StringUtils.isEmpty(clusterName)) {
            throw new IllegalStateException("ElasticSearch 集群名称为空.");
        }
        if (StringUtils.isEmpty(hostList)) {
            throw new IllegalStateException("ElasticSearch 服务列表为空.");
        }
        //设置集群名称：默认是elasticsearch，并设置client.transport.sniff为true，使客户端嗅探整个集群状态，把集群中的其他机器IP加入到客户端中
        Settings settings = Settings.builder().put("cluster.name", clusterName).put("client.transport.sniff", true).build();
        String[] hostAndPorts = hostList.split(",");
        Map<String, Integer> hostInfos = parseHostAndPorts(hostAndPorts);
        transportClient = new PreBuiltTransportClient(settings);
        for (Map.Entry<String, Integer> entry : hostInfos.entrySet()) {
            transportClient.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(entry.getKey()), entry.getValue()));
        }
    }

    private Map<String, Integer> parseHostAndPorts(String[] hostAndPorts) {
        Map<String, Integer> hostMap = new HashMap<String, Integer>();
        if (hostAndPorts == null) {
            return hostMap;
        }
        for (String hostAndPortStr : hostAndPorts) {
            String[] hostAndPort = hostAndPortStr.split(":");
            if (hostAndPort.length != 2) {
                throw new IllegalStateException("配置信息不正确，请使用:符号分隔地址和端口 => " + hostAndPortStr);
            }
            if (!StringUtils.isNumeric(hostAndPort[1])) {
                throw new IllegalStateException("端口号信息不正确 => " + hostAndPort[1]);
            }
            hostMap.put(hostAndPort[0], Integer.parseInt(hostAndPort[1]));
        }
        return hostMap;
    }
}
